package com.sita.friend;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;

import com.easemob.EMCallBack;
import com.easemob.EMConnectionListener;
import com.easemob.EMError;
import com.easemob.EMEventListener;
import com.easemob.EMGroupChangeListener;
import com.easemob.EMNotifierEvent;
import com.easemob.EMValueCallBack;
import com.easemob.chat.CmdMessageBody;
import com.easemob.chat.EMChat;
import com.easemob.chat.EMChatManager;
import com.easemob.chat.EMChatOptions;
import com.easemob.chat.EMContactListener;
import com.easemob.chat.EMContactManager;
import com.easemob.chat.EMGroup;
import com.easemob.chat.EMGroupManager;
import com.easemob.chat.EMMessage;
import com.easemob.exceptions.EaseMobException;
import com.easemob.util.EMLog;
import com.google.gson.reflect.TypeToken;
import com.sita.bike.R;
import com.sita.bike.model.EaseUser2;
import com.sita.bike.rest.RestClient;
import com.sita.bike.rest.model.Account;
import com.sita.bike.rest.model.Account3;
import com.sita.bike.rest.model.ListUserRequest;
import com.sita.bike.rest.model.RestResponse;
import com.sita.bike.support.GlobalContext;
import com.sita.bike.utils.AccountUtils;
import com.sita.bike.utils.LogUtils;
import com.sita.bike.utils.NotificationUtils;
import com.sita.friend.db.DBManager;
import com.sita.friend.db.InviteMessgeDao;
import com.sita.friend.db.UserDao;
import com.sita.friend.domain.InviteMessage;
import com.sita.friend.domain.InviteMessage.InviteMesageStatus;
import com.sita.friend.event.AcceptFriendEvent;
import com.sita.friend.event.AddFriendEvent;
import com.sita.friend.event.ReceiveMessageEvent;
import com.sita.friend.event.ReceviceShareLocOneEvent;
import com.sita.friend.event.ReceviceShareLocRealTimeEvent;
import com.sita.friend.event.ReceviceStopShareLocEvent;
import com.sita.friend.parse.UserProfileManager;
import com.sita.friend.receiver.CallReceiver;
import com.sita.friend.utils.MessageUtils;
import com.sita.friend.utils.PreferenceManager;
import com.sita.tboard.global.LocalConstants;
import com.sita.tboard.hitchhike.bean.TicketStatus;
import com.sita.tboard.hitchhike.event.HitchhikeDriverAcceptTripEvent;
import com.sita.tboard.hitchhike.event.HitchhikePayReceivedEvent;
import com.sita.tboard.hitchhike.event.HitchhikeTripStatusEvent;
import com.sita.tboard.hitchhike.helper.HitchhikePersistHelper;
import com.sita.tboard.ui.tools.L;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import de.greenrobot.event.EventBus;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;

public class FriendHelper {
    protected static final String TAG = FriendHelper.class.getSimpleName();
    private static FriendHelper instance = null;


    //    private Map<String, RobotUser> robotList;
    public boolean isVoiceCalling;
    public boolean isVideoCalling;
    /**
     * EMEventListener
     */
    protected EMEventListener eventListener = null;
    private Map<String, EaseUser2> contactList;
    private EaseUser2 user;
    private UserProfileManager userProManager;
    private FriendModel demoModel = null;
    /**
     * HuanXin sync groups status listener
     */
    private List<DataSyncListener> syncGroupsListeners;
    /**
     * HuanXin sync contacts status listener
     */
    private List<DataSyncListener> syncContactsListeners;
    /**
     * HuanXin sync blacklist status listener
     */
    private List<DataSyncListener> syncBlackListListeners;
    private boolean isSyncingGroupsWithServer = false;
    private boolean isSyncingContactsWithServer = false;
    private boolean isSyncingBlackListWithServer = false;
    private boolean isGroupsSyncedWithServer = false;
    private boolean isContactsSyncedWithServer = false;
    private boolean isBlackListSyncedWithServer = false;
    private boolean alreadyNotified = false;
    private String username;
    private Context appContext;
    private CallReceiver callReceiver;
    private EMConnectionListener connectionListener;
    private InviteMessgeDao inviteMessgeDao;
    private UserDao userDao;
    private LocalBroadcastManager broadcastManager;
    private boolean isGroupAndContactListenerRegisted;
    /**
     * init flag: test if the sdk has been inited before, we don't need to init again
     */
    private boolean sdkInited = false;

    private FriendHelper() {
    }

    public synchronized static FriendHelper getInstance() {
        if (instance == null) {
            instance = new FriendHelper();
        }
        return instance;
    }

    /**
     * init helper
     *
     * @param context application context
     */
    public void init(Context context) {
//        if (EaseUI.getInstance().init(context)) {
        if (initSDK(context)) {
            appContext = context;
            //设为调试模式，打成正式包时，最好设为false，以免消耗额外的资源
            EMChat.getInstance().setDebugMode(false);
            EMChat.getInstance().setAutoLogin(true);

//            //get easeui instance
//            easeUI = EaseUI.getInstance();
//            //调用easeui的api设置providers
//            setEaseUIProviders();
            demoModel = new FriendModel(context);
            //设置chat options
            setChatoptions();
            //初始化PreferenceManager
            PreferenceManager.init(context);
//            //初始化用户管理类
//            getUserProfileManager().init(context);

            //设置全局监听
            setGlobalListeners();
            broadcastManager = LocalBroadcastManager.getInstance(appContext);
            initDbDao();
        }
    }

    /**
     * this function will initialize the HuanXin SDK
     *
     * @param context
     * @return
     */
    public synchronized boolean initSDK(Context context) {
        if (sdkInited) {
            return true;
        }
        appContext = context;

        int pid = android.os.Process.myPid();
        String processAppName = getAppName(pid);

        Log.d(TAG, "process app name : " + processAppName);

        // 如果app启用了远程的service，此application:onCreate会被调用2次
        // 为了防止环信SDK被初始化2次，加此判断会保证SDK被初始化1次
        // 默认的app会在以包名为默认的process name下运行，如果查到的process name不是app的process name就立即返回
        if (processAppName == null || !processAppName.equalsIgnoreCase(appContext.getPackageName())) {
            Log.e(TAG, "enter the service process!");

            // 则此application::onCreate 是被service 调用的，直接返回
            return false;
        }
        // 初始化环信SDK,一定要先调用init()
        EMChat.getInstance().init(context);

        initChatOptions();
//        if(settingsProvider == null){
//            settingsProvider = new DefaultSettingsProvider();
//        }

        sdkInited = true;
        return true;
    }

    protected void initChatOptions() {
        Log.d(TAG, "init HuanXin Options");

        // 获取到EMChatOptions对象
        EMChatOptions options = EMChatManager.getInstance().getChatOptions();
        // 默认添加好友时，是不需要验证的，改成需要验证
        options.setAcceptInvitationAlways(false);
        // 默认环信是不维护好友关系列表的，如果app依赖环信的好友关系，把这个属性设置为true
        options.setUseRoster(false);
        // 设置是否需要已读回执
        options.setRequireAck(true);
        // 设置是否需要已送达回执
        options.setRequireDeliveryAck(false);
        // 设置从db初始化加载时, 每个conversation需要加载msg的个数
        options.setNumberOfMessagesLoaded(1);

//        notifier = createNotifier();
//        notifier.init(appContext);

//        notifier.setNotificationInfoProvider(getNotificationListener());
    }

//    protected void setEaseUIProviders() {
//        //需要easeui库显示用户头像和昵称设置此provider
//        easeUI.setUserProfileProvider(new EaseUserProfileProvider() {
//
//            @Override
//            public EaseUser getUser(String username) {
//                return getUserInfo(username);
//            }
//        });

//        //不设置，则使用easeui默认的
//        easeUI.setSettingsProvider(new EaseSettingsProvider() {
//
//            @Override
//            public boolean isSpeakerOpened() {
//                return demoModel.getSettingMsgSpeaker();
//            }
//
//            @Override
//            public boolean isMsgVibrateAllowed(EMMessage message) {
//                return demoModel.getSettingMsgVibrate();
//            }
//
//            @Override
//            public boolean isMsgSoundAllowed(EMMessage message) {
//                return demoModel.getSettingMsgSound();
//            }
//
//            @Override
//            public boolean isMsgNotifyAllowed(EMMessage message) {
//                if (message == null) {
//                    return demoModel.getSettingMsgNotification();
//                }
//                if (!demoModel.getSettingMsgNotification()) {
//                    return false;
//                } else {
//                    //如果允许新消息提示
//                    //屏蔽的用户和群组不提示用户
//                    String chatUsename = null;
//                    List<String> notNotifyIds = null;
//                    // 获取设置的不提示新消息的用户或者群组ids
//                    if (message.getChatType() == ChatType.Chat) {
//                        chatUsename = message.getFrom();
//                        notNotifyIds = demoModel.getDisabledIds();
//                    } else {
//                        chatUsename = message.getTo();
//                        notNotifyIds = demoModel.getDisabledGroups();
//                    }
//
//                    if (notNotifyIds == null || !notNotifyIds.contains(chatUsename)) {
//                        return true;
//                    } else {
//                        return false;
//                    }
//                }
//            }
//        });

//
//        //不设置，则使用easeui默认的
//        easeUI.getNotifier().setNotificationInfoProvider(new EaseNotificationInfoProvider() {
//
//            @Override
//            public String getTitle(EMMessage message) {
//                //修改标题,这里使用默认
//                return null;
//            }
//
//            @Override
//            public int getSmallIcon(EMMessage message) {
//                //设置小图标，这里为默认
//                return 0;
//            }
//
//            @Override
//            public String getDisplayedText(EMMessage message) {
//                // 设置状态栏的消息提示，可以根据message的类型做相应提示
//                String ticker = EaseCommonUtils.getMessageDigest(message, appContext);
//                if (message.getType() == Type.TXT) {
//                    ticker = ticker.replaceAll("\\[.{2,3}\\]", "[表情]");
//                }
//                EaseUser2 user = getUserInfo(message.getFrom());
//                if (user != null) {
//                    return getUserInfo(message.getFrom()).getNick() + ": " + ticker;
//                } else {
//                    return message.getFrom() + ": " + ticker;
//                }
//            }
//
//            @Override
//            public String getLatestText(EMMessage message, int fromUsersNum, int messageNum) {
//                return null;
//                // return fromUsersNum + "个基友，发来了" + messageNum + "条消息";
//            }
//
//            @Override
//            public Intent getLaunchIntent(EMMessage message) {
//
//                return null; // TODO
////                //设置点击通知栏跳转事件
////                Intent intent = new Intent(appContext, ChatActivity.class);
////                //有电话时优先跳转到通话页面
////                if(isVideoCalling){
////                    intent = new Intent(appContext, VideoCallActivity.class);
////                }else if(isVoiceCalling){
////                    intent = new Intent(appContext, VoiceCallActivity.class);
////                }else{
////                    ChatType chatType = message.getChatType();
////                    if (chatType == ChatType.Chat) { // 单聊信息
////                        intent.putExtra("userId", message.getFrom());
////                        intent.putExtra("chatType", Constant.CHATTYPE_SINGLE);
////                    } else { // 群聊信息
////                        // message.getTo()为群聊id
////                        intent.putExtra("userId", message.getTo());
////                        if(chatType == ChatType.GroupChat){
////                            intent.putExtra("chatType", Constant.CHATTYPE_GROUP);
////                        }else{
////                            intent.putExtra("chatType", Constant.CHATTYPE_CHATROOM);
////                        }
////
////                    }
////                }
////                return intent;
//            }
//        });
//    }

    /**
     * check the application process name if process name is not qualified, then we think it is a service process and we will not init SDK
     *
     * @param pID
     * @return
     */
    private String getAppName(int pID) {
        String processName = null;
        ActivityManager am = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE);
        List l = am.getRunningAppProcesses();
        Iterator i = l.iterator();
        PackageManager pm = appContext.getPackageManager();
        while (i.hasNext()) {
            ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo) (i.next());
            try {
                if (info.pid == pID) {
                    CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
                    // Log.d("Process", "Id: "+ info.pid +" ProcessName: "+
                    // info.processName +"  Label: "+c.toString());
                    // processName = c.toString();
                    processName = info.processName;
                    return processName;
                }
            } catch (Exception e) {
                // Log.d("Process", "Error>> :"+ e.toString());
            }
        }
        return processName;
    }

    private void setChatoptions() {
        //easeui库默认设置了一些options，可以覆盖
        EMChatOptions options = EMChatManager.getInstance().getChatOptions();
        options.allowChatroomOwnerLeave(getModel().isChatroomOwnerLeaveAllowed());
    }

    /**
     * 设置全局事件监听
     */
    protected void setGlobalListeners() {
        syncGroupsListeners = new ArrayList<DataSyncListener>();
        syncContactsListeners = new ArrayList<DataSyncListener>();
        syncBlackListListeners = new ArrayList<DataSyncListener>();

//        isGroupsSyncedWithServer = demoModel.isGroupsSynced();
//        isContactsSyncedWithServer = demoModel.isContactSynced();
//        isBlackListSyncedWithServer = demoModel.isBacklistSynced();

        isGroupsSyncedWithServer = false;
        isContactsSyncedWithServer = false;
        isBlackListSyncedWithServer = false;

        // create the global connection listener
        connectionListener = new EMConnectionListener() {
            @Override
            public void onDisconnected(int error) {
                EMLog.i(TAG, "onDisconnected" + error);
                if (error == EMError.USER_REMOVED) {
                    onCurrentAccountRemoved();
                } else if (error == EMError.CONNECTION_CONFLICT) {
                    onConnectionConflict();
                }
            }

            @Override
            public void onConnected() {
                EMLog.i(TAG, "onConnected");

                // in case group and contact were already synced, we supposed to notify sdk we are ready to receive the events
                if (isGroupsSyncedWithServer && isContactsSyncedWithServer) {
                    new Thread() {
                        @Override
                        public void run() {
                            FriendHelper.getInstance().notifyForRecevingEvents();
                        }
                    }.start();
                } else {
                    if (!isGroupsSyncedWithServer) {
                        asyncFetchGroupsFromServer(null);
                    }

                    // TODO: 2016/1/22
                    if (!isContactsSyncedWithServer) {
                        asyncFetchContactsFromServer(null);
                    }

                    if (!isBlackListSyncedWithServer) {
                        asyncFetchBlackListFromServer(null);
                    }
                }
            }
        };


//        IntentFilter callFilter = new IntentFilter(EMChatManager.getInstance().getIncomingCallBroadcastAction());
//        if (callReceiver == null) {
//            callReceiver = new CallReceiver();
//        }
//
//        //注册通话广播接收者
//        appContext.registerReceiver(callReceiver, callFilter);

        //注册连接监听
        EMChatManager.getInstance().addConnectionListener(connectionListener);
        //注册群组和联系人监听
        registerGroupAndContactListener();
        //注册消息事件监听
        registerEventListener();
        EMChat.getInstance().setAppInited(); // Must Important

    }

    public void syncFromServer() {
        L.i("syncFromServer() at " + new Date());
        ListUserRequest request = new ListUserRequest();
        request.mAccountId = AccountUtils.getAccountID();

        RestClient.getRestNormalService().listUser(request, new Callback<RestResponse>() {
            @Override
            public void success(RestResponse restResponse, Response response) {
                if (response.getStatus() == 200 && restResponse.mErrorCode.equals("0")) {

                    try {
                        String s = RestClient.getGson().toJson(restResponse.mData);
                        List<Account3> userlist = RestClient.getGson().fromJson(s, new TypeToken<List<Account3>>() {
                        }.getType());

                        // 储存好友列表信息
                        AccountUtils.saveFriendList(userlist);

                        demoModel.setContactSynced(true);
                        EMLog.d(TAG, "asyncFetchContactsFromServer total:" + userlist.size());

                    } catch (Exception e) {
                        L.e("syncFromServer()", e);
                    }
                }
            }

            @Override
            public void failure(RetrofitError error) {
                L.e("syncFromServer()", error);
                EMLog.d(TAG, "asyncFetchContactsFromServer failed");
            }
        });
    }

    private void initDbDao() {
        inviteMessgeDao = new InviteMessgeDao(appContext);
        userDao = new UserDao(appContext);
    }

    /**
     * 注册群组和联系人监听，由于logout的时候会被sdk清除掉，再次登录的时候需要再注册一下
     */
    public void registerGroupAndContactListener() {
        if (!isGroupAndContactListenerRegisted) {
            //注册群组变动监听
            EMGroupManager.getInstance().addGroupChangeListener(new MyGroupChangeListener());
            //注册联系人变动监听
            EMContactManager.getInstance().setContactListener(new MyContactListener());
            isGroupAndContactListenerRegisted = true;
        }

    }

    public void notifyContactInvited(String username, String reason, String id) {
        if (TextUtils.isEmpty(username)) {
            return;
        }
        InviteMessage msg = MessageUtils.createFriendMessage(username, id, InviteMesageStatus.BEINVITEED);
        MessageUtils.notifyNewInviteMessage(msg);
        broadcastManager.sendBroadcast(new Intent(Constant.ACTION_CONTACT_CHANAGED));
    }

    public void notifyContactAgreed(String username, String id) {
        InviteMessage msg = MessageUtils.createFriendMessage(username, id, InviteMesageStatus.BEAGREED);
        MessageUtils.notifyNewInviteMessage(msg);
        String content = appContext.getResources().getString(R.string.friend_accepted_message);
        MessageUtils.createTxtMessage(id, AccountUtils.getAccountID(), username + content, false);
//        MessageUtils.sendTxtMessage(id, AccountUtils.getUserDisplayName() + content);

        broadcastManager.sendBroadcast(new Intent(Constant.ACTION_CONTACT_CHANAGED));
    }


    /**
     * 群组变动监听
     */
    class MyGroupChangeListener implements EMGroupChangeListener {

        @Override
        public void onInvitationReceived(String groupId, String groupName, String inviter, String reason) {

            boolean hasGroup = false;
            for (EMGroup group : EMGroupManager.getInstance().getAllGroups()) {
                if (group.getGroupId().equals(groupId)) {
                    hasGroup = true;
                    break;
                }
            }
            if (!hasGroup)
                return;

            // Request Group Info from sita server.
            AccountUtils.saveGroupMembers(groupId, true);

            // 被邀请
            String content = appContext.getResources().getString(R.string.group_invitation_message);
            MessageUtils.createTxtMessage(inviter, groupId, inviter + content, true);
//            EMMessage msg = EMMessage.createReceiveMessage(EMMessage.Type.TXT);
//            msg.setChatType(EMMessage.ChatType.GroupChat);
//            msg.setFrom(inviter);
//            msg.setTo(groupId);
//            msg.setMsgId(UUID.randomUUID().toString());
//            msg.addBody(new TextMessageBody(st3));
//            // 保存邀请消息
//            EMChatManager.getInstance().saveMessage(msg);
//            // 提醒新消息
//            getNotifier().viberateAndPlayTone(msg);
//            //发送local广播
            broadcastManager.sendBroadcast(new Intent(Constant.ACTION_GROUP_CHANAGED));
        }

        @Override
        public void onInvitationAccpted(String groupId, String inviter, String reason) {
        }

        @Override
        public void onInvitationDeclined(String groupId, String invitee, String reason) {
        }

        @Override
        public void onUserRemoved(String groupId, String groupName) {
            //TODO 提示用户被T了，demo省略此步骤
        }

        @Override
        public void onGroupDestroy(String groupId, String groupName) {
            //TODO 提示用户群被解散,demo省略
        }

        @Override
        public void onApplicationReceived(String groupId, String groupName, String applyer, String reason) {
//
//            // 用户申请加入群聊
//            InviteMessage msg = new InviteMessage();
//            msg.setFrom(applyer);
//            msg.setTime(System.currentTimeMillis());
//            msg.setGroupId(groupId);
//            msg.setGroupName(groupName);
//            msg.setReason(reason);
//            Log.d(TAG, applyer + " 申请加入群聊：" + groupName);
//            msg.setStatus(InviteMesageStatus.BEAPPLYED);
//            notifyNewIviteMessage(msg);
//            broadcastManager.sendBroadcast(new Intent(Constant.ACTION_GROUP_CHANAGED));
        }

        @Override
        public void onApplicationAccept(String groupId, String groupName, String accepter) {

//            String st4 = appContext.getString(com.easemob.easeui.R.string.Agreed_to_your_group_chat_application);
//            // 加群申请被同意
//            EMMessage msg = EMMessage.createReceiveMessage(Type.TXT);
//            msg.setChatType(ChatType.GroupChat);
//            msg.setFrom(accepter);
//            msg.setTo(groupId);
//            msg.setMsgId(UUID.randomUUID).toString());
//            msg.addBody(new TextMessageBody(accepter + " " + st4));
//            // 保存同意消息
//            EMChatManager.getInstance().saveMessage(msg);
//            // 提醒新消息
//            getNotifier().viberateAndPlayTone(msg);
//            broadcastManager.sendBroadcast(new Intent(Constant.ACTION_GROUP_CHANAGED));
        }

        @Override
        public void onApplicationDeclined(String groupId, String groupName, String decliner, String reason) {
            // 加群申请被拒绝，demo未实现
        }
    }

    /***
     * 好友变化listener
     */

    // // TODO: 2016/1/20 replace the listener by own

    public class MyContactListener implements EMContactListener {

        @Override
        public void onContactAdded(List<String> usernameList) {
            LogUtils.i(TAG, "MyContactListener onContactAdded");
        }

        @Override
        public void onContactDeleted(final List<String> usernameList) {
            LogUtils.e(TAG, "MyContactListener onContactDeleted");
        }

        @Override
        public void onContactInvited(String username, String reason) {
            LogUtils.e(TAG, "MyContactListener onContactInvited");
        }

        @Override
        public void onContactAgreed(String username) {
            LogUtils.i(TAG, "MyContactListener onContactAgreed");
        }

        @Override
        public void onContactRefused(String username) {
            LogUtils.i(TAG, "MyContactListener onContactRefused");
        }
    }

    /**
     * 账号在别的设备登录
     */
    protected void onConnectionConflict() {
//        Intent intent = new Intent(appContext, RoadTrustMainActivity.class);
//        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//        intent.putExtra(Constant.ACCOUNT_CONFLICT, true);
//        appContext.startActivity(intent);
    }

    /**
     * 账号被移除
     */
    protected void onCurrentAccountRemoved() {
//        Intent intent = new Intent(appContext, RoadTrustMainActivity.class);
//        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//        intent.putExtra(Constant.ACCOUNT_REMOVED, true);
//        appContext.startActivity(intent);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 全局事件监听
     * 因为可能会有UI页面先处理到这个消息，所以一般如果UI页面已经处理，这里就不需要再次处理
     * activityList.size() <= 0 意味着所有页面都已经在后台运行，或者已经离开Activity Stack
     */
    protected void registerEventListener() {
        eventListener = new EMEventListener() {
            private BroadcastReceiver broadCastReceiver = null;

            @Override
            public void onEvent(EMNotifierEvent event) {
                EMMessage message = null;
                if (event.getData() instanceof EMMessage) {
                    message = (EMMessage) event.getData();
                    LogUtils.d(TAG, "receive the event : " + event.getEvent() + ",id : " + message.getMsgId());
                }
                switch (event.getEvent()) {
                    case EventNewMessage:
                        // TODO: 2016/1/21
//                        //应用在后台，不需要刷新UI,通知栏提示新消息
//                        if (!easeUI.hasForegroundActivies()) {
//                            getNotifier().onNewMsg(message);
//                        }
                        EventBus.getDefault().post(new ReceiveMessageEvent("EventNewMessage", message));
                        break;
                    case EventOfflineMessage:
                        // TODO: 2016/1/21
//                        if (!easeUI.hasForegroundActivies()) {
//                            EMLog.d(TAG, "received offline messages");
//                            List<EMMessage> messages = (List<EMMessage>) event.getData();
//                            getNotifier().onNewMesg(messages);
//                        }
                        break;
                    // below is just giving a example to show a cmd toast, the app should not follow this
                    // so be careful of this
                    case EventNewCMDMessage: {
                        LogUtils.d(TAG, "收到透传消息");
                        //获取消息body
                        CmdMessageBody cmdMsgBody = (CmdMessageBody) message.getBody();
                        final String action = cmdMsgBody.action;//获取自定义action

                        Account fromUser = new Account();
                        try {
                            JSONObject attr = message.getJSONObjectAttribute(Constant.ATTR_FROM_USER);
                            if (attr.has("accountId")) {
                                fromUser.mAccountId = attr.getString("accountId");
                            }
                            if (attr.has("mobile")) {
                                fromUser.mMobile = attr.getString("mobile");
                            }
                            if (attr.has("name")) {
                                fromUser.mNickName = attr.getString("name");
                            }
                            if (attr.has("nickName") && TextUtils.isEmpty(fromUser.mNickName)) {
                                fromUser.mNickName = attr.getString("nickName");
                            }
                            if (attr.has("avatar")) {
                                fromUser.mAvatar = attr.getString("avatar");
                            }
                            if (attr.has("gender")) {
                                fromUser.mGender = attr.getInt("gender");
                            }

                        } catch (EaseMobException | JSONException e) {

                        }

                        String username = "";
                        if (fromUser != null) {
                            username = !TextUtils.isEmpty(fromUser.mNickName) ? fromUser.mNickName : fromUser.mMobile;
                        }
                        L.i("registerEventListener()-->Received action=[ %s ], message=[ %s ]", action, message);
                        switch (action) {
                            case Constant.CMD_ADD_FRIEND: {
                                if (!TextUtils.isEmpty(username)) {
                                    LogUtils.d(TAG, "add friend cmd from " + username);
                                    notifyContactInvited(username, appContext.getString(R.string.contact_add_request_content), fromUser.mAccountId);
                                    AccountUtils.savePendingFriend(fromUser);

                                    EventBus.getDefault().post(new AddFriendEvent(fromUser.mAccountId));
                                }
                                break;
                            }

                            case Constant.CMD_ACCEPT_FRIEND: {
                                if (!TextUtils.isEmpty(username)) {
                                    LogUtils.d(TAG, "accept friend cmd from " + username);
                                    // should fetch the friend detail info
                                    AccountUtils.asyncFetchFriendInfo(fromUser.mAccountId, new AccountUtils.AsyncFetchFriendInfoListener() {
                                        @Override
                                        public void success(Account account) {
                                            AccountUtils.saveFriend(account);
                                            EventBus.getDefault().post(new AcceptFriendEvent(account.mAccountId));
                                        }

                                        @Override
                                        public void failed() {
                                            LogUtils.e(TAG, "CMD_ACCEPT_FRIEND asyncFetchFriendInfo failed");
                                        }
                                    });
                                    notifyContactAgreed(username, fromUser.mAccountId);
                                }
                                break;
                            }
                            case Constant.SHARE_LOC_ACTION_ONE_SHOT: {
                                EventBus.getDefault().post(new ReceviceShareLocOneEvent("recevice share loc action one shot", message));
                                break;
                            }
                            case Constant.SHARE_LOC_ACTION_REAL_TIME: {
                                EventBus.getDefault().post(new ReceviceShareLocRealTimeEvent("recevice share loc action real time", message));
                                break;
                            }
                            case Constant.SHARE_LOC_ACTION_STOP_REAL_TIME: {
                                EventBus.getDefault().post(new ReceviceStopShareLocEvent("recevice stop share loc action ", message));
                                break;
                            }
                            /*case Constant.MODI_CALLCAR: {
                                if (!LocalConstants.CALLCAR_ENABLED) {
                                    break;
                                }
                                CallcarBean callcarBean = new CallcarBean();
                                try {
                                    JSONObject attr = message.getJSONObjectAttribute("moDiCallCar");
                                    if (attr.has("rentTripId")){
                                        callcarBean.rentTripId = attr.getString("rentTripId");
                                    }
                                    if (attr.has("start_lat")){
                                        callcarBean.startLat = attr.getDouble("start_lat");
                                    }
                                    if (attr.has("start_lng")){
                                        callcarBean.startLng = attr.getDouble("start_lng");
                                    }
                                    if (attr.has("end_lat")){
                                        callcarBean.endLat = attr.getDouble("end_lat");
                                    }
                                    if (attr.has("end_lng")){
                                        callcarBean.endLng = attr.getDouble("end_lng");
                                    }
                                    if (attr.has("account_custom")){
                                        callcarBean.accountCustom = attr.getString("account_custom");
                                    }
                                    if (attr.has("money")){
                                        callcarBean.money = attr.getDouble("money");
                                    }
                                    if (attr.has("order_begin_time")){
                                        callcarBean.orderBeginTime = attr.getLong("order_begin_time");
                                    }
                                    if (attr.has("fromaddress")){
                                        callcarBean.fromaddress = attr.getString("fromaddress");
                                    }
                                    if (attr.has("toaddress")){
                                        callcarBean.toaddress = attr.getString("toaddress");
                                    }
                                    if (attr.has("mobile")){
                                        callcarBean.mobile = attr.getString("mobile");
                                    }
                                    if (attr.has("nickname")){
                                        callcarBean.nickname = attr.getString("nickname");
                                    }
                                } catch (Exception e) {
                                    L.e("registerEventListener()", e);
                                }
                                EventBus.getDefault().post(new CallcarReceivedEvent(callcarBean));
                                break;
                            }*/
                            case Constant.MODI_ACCEPT: {
                                if (!LocalConstants.isHitchhikeEnabled()) {
                                    break;
                                }
                                HitchhikeDriverAcceptTripEvent hitchhikeEvent = new HitchhikeDriverAcceptTripEvent();
                                try {
                                    JSONObject attr = message.getJSONObjectAttribute(Constant.MODI_ACCEPT_ATTRIBUTE);
                                    if (attr.has("rentTripId")) {
                                        hitchhikeEvent.setRentTripId(attr.getString("rentTripId"));
                                    }
                                    if (attr.has("knightId")) {
                                        hitchhikeEvent.setKnightId(attr.getString("knightId"));
                                    }
                                    if (attr.has("lat")) {
                                        hitchhikeEvent.setLat(attr.getDouble("lat"));
                                    }
                                    if (attr.has("lng")) {
                                        hitchhikeEvent.setLng(attr.getDouble("lng"));
                                    }
                                    if (attr.has("accepttime")) {
                                        hitchhikeEvent.setAccepttime(attr.getLong("accepttime"));
                                    }
                                    if (attr.has("status")) {
                                        hitchhikeEvent.setStatus(attr.getInt("status"));
                                    }
                                } catch (Exception e) {
                                    L.e("registerEventListener()", e);
                                }

                                long ticketId = Long.valueOf(hitchhikeEvent.getRentTripId());
                                String driverId = hitchhikeEvent.getKnightId();
                                HitchhikePersistHelper.INSTANCE.updatePassengerTicketStatus(ticketId,
                                        TicketStatus.getInstance().ACCEPTED, driverId);

                                EventBus.getDefault().post(hitchhikeEvent);
                                break;
                            }
                            case Constant.MODI_STATUS: {
                                if (!LocalConstants.isHitchhikeEnabled()) {
                                    break;
                                }
                                HitchhikeTripStatusEvent hitchhikeEvent = new HitchhikeTripStatusEvent();
                                try {
                                    JSONObject attr = message.getJSONObjectAttribute(Constant.MODI_STATUS_ATTRIBUTE);
                                    if (attr.has("rentTripId")) {
                                        hitchhikeEvent.setRentTripId(Long.valueOf(attr.getString("rentTripId")));
                                    }
                                    if (attr.has("status")) {
                                        hitchhikeEvent.setStatus(attr.getInt("status"));
                                    }
                                } catch (Exception e) {
                                    L.e("registerEventListener()", e);
                                }

                                Long tripId = hitchhikeEvent.getRentTripId();
                                HitchhikePersistHelper.INSTANCE.updatePassengerTicketStatus(tripId, hitchhikeEvent.getStatus());
                                HitchhikePersistHelper.INSTANCE.updateDriverTicketStatus(tripId, hitchhikeEvent.getStatus());

                                EventBus.getDefault().post(hitchhikeEvent);
                                break;
                            }
                            case Constant.MODI_PAY: {
                                if (!LocalConstants.isHitchhikeEnabled()) {
                                    break;
                                }
                                HitchhikePayReceivedEvent payEvent = new HitchhikePayReceivedEvent();
                                try {
                                    JSONObject attr = message.getJSONObjectAttribute(Constant.MODI_PAY_ATTRIBUTE);
                                    if (attr.has("accountId")) {
                                        payEvent.setAccountId(attr.getString("accountId"));
                                    }
                                    if (attr.has("money")) {
                                        payEvent.setMoney(attr.getDouble("money"));
                                    }
                                    if (attr.has("targetId")) {
                                        payEvent.setTargetId(attr.getString("targetId"));
                                    }
                                    if (attr.has("rentTripId")) {
                                        payEvent.setRentTripId(attr.getString("rentTripId"));
                                    }
                                    if (attr.has("status")) {
                                        payEvent.setStatus(attr.getInt("status"));
                                    }
                                } catch (Exception e) {
                                    L.e("registerEventListener()", e);
                                }
                                HitchhikePersistHelper.INSTANCE.deleteDriverTicket(Long.valueOf(payEvent.getRentTripId()));
                                EventBus.getDefault().post(payEvent);
                                break;
                            }
                            case Constant.NOTIFICATION_NEW_TREND: {
                                LogUtils.d(TAG, "get new trend notification");
                                String title = message.getStringAttribute("title", "");
                                String resourceId = message.getStringAttribute("resourceId", "");
                                NotificationUtils.notifyNewTrendPublished(GlobalContext.getGlobalContext(), title, resourceId);
                                break;
                            }
                            default:
                                break;
                        }

                        L.i("registerEventListener()", appContext.getString(R.string.receive_the_passthrough, action, message.toString()));

                        break;
                    }
                    case EventDeliveryAck:
                        message.setDelivered(true);
                        break;
                    case EventReadAck:
                        message.setAcked(true);
                        break;
                    // add other events in case you are interested in
                    default:
                        break;
                }

            }
        };

        EMChatManager.getInstance().registerEventListener(eventListener);
    }

    /**
     * 是否登录成功过
     *
     * @return
     */
    public boolean isLoggedIn() {
        return EMChat.getInstance().isLoggedIn();
    }

    /**
     * 退出登录
     *
     * @param unbindDeviceToken 是否解绑设备token(使用GCM才有)
     * @param callback          callback
     */
    public void logout(boolean unbindDeviceToken, final EMCallBack callback) {
//        endCall();
        EMChatManager.getInstance().logout(unbindDeviceToken, new EMCallBack() {

            @Override
            public void onSuccess() {
                reset();
                if (callback != null) {
                    callback.onSuccess();
                }

            }

            @Override
            public void onProgress(int progress, String status) {
                if (callback != null) {
                    callback.onProgress(progress, status);
                }
            }

            @Override
            public void onError(int code, String error) {
                if (callback != null) {
                    callback.onError(code, error);
                }
            }
        });
    }

    /**
     * 获取消息通知类
     *
     * @return
     */
    // TODO: 2016/1/21

//    public EaseNotifier getNotifier() {
//        return easeUI.getNotifier();
//    }
    public FriendModel getModel() {
        return (FriendModel) demoModel;
    }

    /**
     * 保存单个user
     */
    public void saveContact(EaseUser2 user) {
        // TODO: 2016/1/21
        contactList.put(user.getUsername(), user);
        demoModel.saveContact(user);
    }

    /**
     * 获取好友list
     *
     * @return
     */
    public Map<String, EaseUser2> getContactList() {
//        if (isLoggedIn() && contactList == null) {
        if (contactList == null) {
            contactList = demoModel.getContactList();
        }

        return contactList;
    }

    /**
     * 设置好友user list到内存中
     *
     * @param contactList
     */
    public void setContactList(Map<String, EaseUser2> contactList) {
        this.contactList = contactList;
    }

    /**
     * 根据accountId获取单个user
     *
     * @return
     */
    public EaseUser2 getContactUser(String accountId) {

        return demoModel.getContactUser(accountId);
    }

    /**
     * 设置当前用户的环信id
     *
     * @param username
     */
    public void setCurrentUserName(String username) {
        this.username = username;
        demoModel.setCurrentUserName(username);
    }

    /**
     * 获取当前用户的环信id
     */
    public String getCurrentUsernName() {
        if (username == null) {
            username = demoModel.getCurrentUsernName();
        }
        return username;
    }

    /**
     * update user list to cache And db
     */
    public void updateContactList(List<EaseUser2> contactInfoList) {
        for (EaseUser2 u : contactInfoList) {
            contactList.put(u.getUsername(), u);
        }
        ArrayList<EaseUser2> mList = new ArrayList<EaseUser2>();
        mList.addAll(contactList.values());
        demoModel.saveContactList(mList);
    }

    public UserProfileManager getUserProfileManager() {
        if (userProManager == null) {
            userProManager = new UserProfileManager();
        }
        return userProManager;
    }

    void endCall() {
        try {
            EMChatManager.getInstance().endCall();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//    public void setRobotList(Map<String, RobotUser> robotList) {
//        this.robotList = robotList;
//    }

//    public Map<String, RobotUser> getRobotList() {
//        if (isLoggedIn() && robotList == null) {
//            robotList = demoModel.getRobotList();
//        }
//        return robotList;
//    }

    public void addSyncGroupListener(DataSyncListener listener) {
        if (listener == null) {
            return;
        }
        if (!syncGroupsListeners.contains(listener)) {
            syncGroupsListeners.add(listener);
        }
    }

    public void removeSyncGroupListener(DataSyncListener listener) {
        if (listener == null) {
            return;
        }
        if (syncGroupsListeners.contains(listener)) {
            syncGroupsListeners.remove(listener);
        }
    }

    public void addSyncContactListener(DataSyncListener listener) {
        if (listener == null) {
            return;
        }
        if (!syncContactsListeners.contains(listener)) {
            syncContactsListeners.add(listener);
        }
    }

    public void removeSyncContactListener(DataSyncListener listener) {
        if (listener == null) {
            return;
        }
        if (syncContactsListeners.contains(listener)) {
            syncContactsListeners.remove(listener);
        }
    }

    public void addSyncBlackListListener(DataSyncListener listener) {
        if (listener == null) {
            return;
        }
        if (!syncBlackListListeners.contains(listener)) {
            syncBlackListListeners.add(listener);
        }
    }

    public void removeSyncBlackListListener(DataSyncListener listener) {
        if (listener == null) {
            return;
        }
        if (syncBlackListListeners.contains(listener)) {
            syncBlackListListeners.remove(listener);
        }
    }

    /**
     * 同步操作，从服务器获取群组列表
     * 该方法会记录更新状态，可以通过isSyncingGroupsFromServer获取是否正在更新
     * 和isGroupsSyncedWithServer获取是否更新已经完成
     *
     * @throws EaseMobException
     */
    public synchronized void asyncFetchGroupsFromServer(final EMCallBack callback) {
        if (isSyncingGroupsWithServer) {
            return;
        }

        isSyncingGroupsWithServer = true;

        new Thread() {
            @Override
            public void run() {
                try {
                    EMGroupManager.getInstance().getGroupsFromServer();

                    // in case that logout already before server returns, we should return immediately
                    if (!EMChat.getInstance().isLoggedIn()) {
                        return;
                    }

                    demoModel.setGroupsSynced(true);

                    isGroupsSyncedWithServer = true;
                    isSyncingGroupsWithServer = false;

                    //通知listener同步群组完毕
                    noitifyGroupSyncListeners(true);
                    if (isContactsSyncedWithServer()) {
                        notifyForRecevingEvents();
                    }
                    if (callback != null) {
                        callback.onSuccess();
                    }
                } catch (EaseMobException e) {
                    demoModel.setGroupsSynced(false);
                    isGroupsSyncedWithServer = false;
                    isSyncingGroupsWithServer = false;
                    noitifyGroupSyncListeners(false);
                    if (callback != null) {
                        callback.onError(e.getErrorCode(), e.toString());
                    }
                }

            }
        }.start();
    }

    public void noitifyGroupSyncListeners(boolean success) {
        for (DataSyncListener listener : syncGroupsListeners) {
            listener.onSyncComplete(success);
        }
    }

    // 同步好友信息
    public void asyncFetchContactsFromServer(final EMValueCallBack<List<String>> callback) {
        LogUtils.i(TAG, "asyncFetchContactsFromServer started");
        if (isSyncingContactsWithServer) {
            return;
        }

        isSyncingContactsWithServer = true;

        // 获取好友列表
        ListUserRequest request = new ListUserRequest();
        request.mAccountId = AccountUtils.getAccountID();

        RestClient.getRestNormalService().listUser(request, new Callback<RestResponse>() {
            @Override
            public void success(RestResponse restResponse, Response response) {
                if (response.getStatus() == 200 && restResponse.mErrorCode.equals("0")) {

                    try {
                        String s = RestClient.getGson().toJson(restResponse.mData);
                        List<Account3> userlist = RestClient.getGson().fromJson(s, new TypeToken<List<Account3>>() {
                        }.getType());

                        // 储存好友列表信息
                        AccountUtils.saveFriendList(userlist);

                        demoModel.setContactSynced(true);
                        EMLog.d(TAG, "asyncFetchContactsFromServer total:" + userlist.size());

                    } catch (Exception e) {

                    }
                }
            }

            @Override
            public void failure(RetrofitError error) {
                EMLog.d(TAG, "asyncFetchContactsFromServer failed");
            }
        });


//        new Thread() {
//            @Override
//            public void run() {
//                List<String> usernames = null;
//                try {
//                    usernames = EMContactManager.getInstance().getContactUserNames();
//                    // in case that logout already before server returns, we should return immediately
//                    if (!EMChat.getInstance().isLoggedIn()) {
//                        return;
//                    }
//
//                    Map<String, EaseUser2> userlist = new HashMap<String, EaseUser2>();
//                    for (String username : usernames) {
//                        EaseUser2 user = new EaseUser2(username);
////                        EaseCommonUtils.setUserInitialLetter(user);
//                        userlist.put(username, user);
//                    }
//                    // 存入内存
//                    getContactList().clear();
//                    getContactList().putAll(userlist);
//                    // 存入db
//                    UserDao dao = new UserDao(appContext);
//                    List<EaseUser2> users = new ArrayList<EaseUser2>(userlist.values());
//                    dao.saveContactList(users);
//
//                    demoModel.setContactSynced(true);
//                    EMLog.d(TAG, "set contact syn status to true");
//
//                    isContactsSyncedWithServer = true;
//                    isSyncingContactsWithServer = false;
//
//                    //通知listeners联系人同步完毕
//                    notifyContactsSyncListener(true);
//                    if (isGroupsSyncedWithServer()) {
//                        notifyForRecevingEvents();
//                    }
//
//// TODO: 2016/1/19 sync from server
////                    getUserProfileManager().asyncFetchContactInfosFromServer(usernames, new EMValueCallBack<List<EaseUser>>() {
////
////                        @Override
////                        public void onSuccess(List<EaseUser2> uList) {
////                            updateContactList(uList);
////                            getUserProfileManager().notifyContactInfosSyncListener(true);
////                        }
////
////                        @Override
////                        public void onError(int error, String errorMsg) {
////                        }
////                    });
//                    if (callback != null) {
//                        callback.onSuccess(usernames);
//                    }
//                } catch (EaseMobException e) {
//                    demoModel.setContactSynced(false);
//                    isContactsSyncedWithServer = false;
//                    isSyncingContactsWithServer = false;
//                    noitifyGroupSyncListeners(false);
//                    e.printStackTrace();
//                    if (callback != null) {
//                        callback.onError(e.getErrorCode(), e.toString());
//                    }
//                }
//
//            }
//        }.start();
    }

    public void notifyContactsSyncListener(boolean success) {
        for (DataSyncListener listener : syncContactsListeners) {
            listener.onSyncComplete(success);
        }
    }

    public void asyncFetchBlackListFromServer(final EMValueCallBack<List<String>> callback) {

        if (isSyncingBlackListWithServer) {
            return;
        }

        isSyncingBlackListWithServer = true;

        new Thread() {
            @Override
            public void run() {
                try {
                    List<String> usernames = EMContactManager.getInstance().getBlackListUsernamesFromServer();

                    // in case that logout already before server returns, we should return immediately
                    if (!EMChat.getInstance().isLoggedIn()) {
                        return;
                    }

                    demoModel.setBlacklistSynced(true);

                    isBlackListSyncedWithServer = true;
                    isSyncingBlackListWithServer = false;

                    EMContactManager.getInstance().saveBlackList(usernames);
                    notifyBlackListSyncListener(true);
                    if (callback != null) {
                        callback.onSuccess(usernames);
                    }
                } catch (EaseMobException e) {
                    demoModel.setBlacklistSynced(false);

                    isBlackListSyncedWithServer = false;
                    isSyncingBlackListWithServer = true;
                    e.printStackTrace();

                    if (callback != null) {
                        callback.onError(e.getErrorCode(), e.toString());
                    }
                }

            }
        }.start();
    }

    public void notifyBlackListSyncListener(boolean success) {
        for (DataSyncListener listener : syncBlackListListeners) {
            listener.onSyncComplete(success);
        }
    }

    public boolean isSyncingGroupsWithServer() {
        return isSyncingGroupsWithServer;
    }

    public boolean isSyncingContactsWithServer() {
        return isSyncingContactsWithServer;
    }

    public boolean isSyncingBlackListWithServer() {
        return isSyncingBlackListWithServer;
    }

    public boolean isGroupsSyncedWithServer() {
        return isGroupsSyncedWithServer;
    }

    public boolean isContactsSyncedWithServer() {
        return isContactsSyncedWithServer;
    }

    public boolean isBlackListSyncedWithServer() {
        return isBlackListSyncedWithServer;
    }

    public synchronized void notifyForRecevingEvents() {
        if (alreadyNotified) {
            return;
        }

        // 通知sdk，UI 已经初始化完毕，注册了相应的receiver和listener, 可以接受broadcast了
        EMChat.getInstance().setAppInited();
        alreadyNotified = true;
    }

    synchronized void reset() {
        isSyncingGroupsWithServer = false;
        isSyncingContactsWithServer = false;
        isSyncingBlackListWithServer = false;

        demoModel.setGroupsSynced(false);
        demoModel.setContactSynced(false);
        demoModel.setBlacklistSynced(false);

        isGroupsSyncedWithServer = false;
        isContactsSyncedWithServer = false;
        isBlackListSyncedWithServer = false;

        alreadyNotified = false;
        isGroupAndContactListenerRegisted = false;

        setContactList(null);
//        setRobotList(null);
//        getUserProfileManager().reset();
        DBManager.getInstance().closeDB();
    }

    public void pushActivity(Activity activity) {
        // TODO: 2016/1/21
//        easeUI.pushActivity(activity);
    }

    public void popActivity(Activity activity) {
        // TODO: 2016/1/21
//        easeUI.popActivity(activity);
    }

    /**
     * 数据同步listener
     */
    static public interface DataSyncListener {
        /**
         * 同步完毕
         *
         * @param success true：成功同步到数据，false失败
         */
        public void onSyncComplete(boolean success);
    }

}
